const { MIME_TYPE_EPUB, UPLOAD_URL, UPLOAD_PATH, OLD_UPLOAD_URL } = require('../utils/constant')
const fs = require('fs')
const path = require('path')
const Epub = require('../utils/epub')
const xml2js = require('xml2js').parseString

// 创建book对象
class Book {
	constructor(file, data) {
		if(file) {
			this.createBookFromFile(file)
		} else {
			this.createBookFromData(data)
		}
	}

	createBookFromFile(fail) {
		console.log('createBookFromFile', fail)
		// 获取书本信息
		const {
			destination,
			filename,
			mimetype = MIME_TYPE_EPUB,
			path,
			originalname
		} = fail
		// 为书本文件添加后缀名
		const suffix = mimetype === MIME_TYPE_EPUB ? '.epub' : ''
		// 电子书的原有路径
		const oldBookPath = path
		// 获取文件路径
		const bookPath = `${destination}/${filename}${suffix}`
		// 获取图书的下载路径
		const url = `${UPLOAD_URL}/book/${filename}${suffix}`
		// 文件解压后的存放路径
		const	unzipPath = `${UPLOAD_PATH}/unzip/${filename}`
		// 获取解压后图书的下载路径
		const unzipUrl = `${UPLOAD_URL}/unzip/${filename}`
		// 上传成功后创建文件夹
		if(!fs.existsSync(unzipPath)) {
			fs.mkdirSync(unzipPath, { recursive: true })
		}
		if(fs.existsSync(oldBookPath) && !fs.existsSync(bookPath)) {
			fs.renameSync(oldBookPath, bookPath)
		}
	
		this.fileName = filename 	// 文件名
		this.path = `/book/${filename}${suffix}`	// epub文件的相对路径
		this.filePath = this.path
		this.unzipPath = `/unzip/${filename}`	// epub解压后相对路径
		this.url = url	// epub 文件下载链接
		this.title = ''	// 书名
		this.author = ''	// 作者
		this.publisher = ''	// 出版社
		this.contents = []	// 目录
		this.contentsTree = []	// 树状目录结构
		this.cover = ''	// 封面图片URL
		this.categoryText = ''	// 分类名称
		this.language = ''	// 语种
		this.unzipUrl = unzipUrl	 // 解压后文件夹链接
		this.originalName = originalname // 电子书文件的原名
	}

	createBookFromData(data) {
		this.fileName = data.fileName
		this.cover = data.cover
		this.title = data.title
		this.author = data.author
		this.publisher = data.publisher
		this.bookId = data.fileName
		this.language = data.language
		this.rootFile = data.rootFile
		this.originalName = data.originalName
		this.path = data.path || data.filePath
		this.filePath = data.path || data.filePath
		this.unzipPath = data.unzipPath
		this.coverPath = data.cover
		this.createUser = data.username
		this.createDt = new Date().getTime()
		this.updateDt = new Date().getTime()
		this.updateType = data.updateType === 0 ? data.updateType : 1
		this.category = data.category || 99	// 分类
		this.categoryText = data.categoryText || '自定义'
		// console.log('data', data)
		this.contents = data.contents || []
	}

	parse() {
		return new Promise((resolve, reject) => {
			// 获取电子书的路径
			const bookPath = `${UPLOAD_PATH}${this.filePath}`
			if(!fs.existsSync(bookPath)) {
				reject(new Error('电子书不存在'))
			}
			// 将图书路径传入到ebook文件中
			const epub = new Epub(bookPath)
			epub.on('error' ,err => {
				reject(err)
			})
			epub.on('end', err => {
				if(err) {
					reject(err)
				} else {
					// 解析完成
					console.log('epub end' ,epub)
					const {
						language,
						creator,
						creatorFileAs,
						title,
						cover,
						publisher
					} = epub.metadata
					if(!title) {
						reject(new Error('图书标题为空'))
					} else {
						this.title = title
						this.language = language || 'en'
						this.author = creator || creatorFileAs || 'unknown'
						this.publisher = publisher || 'unknown'
						this.rootFile = epub.rootFile
						const handleGetImage = (err, file, mimetype) => {
							if(err) {
								reject(err)
							} else {
								const suffix = mimetype.split('/')[1]
								// 封面路径
								const coverPath = `${UPLOAD_PATH}/img/${this.fileName}.${suffix}`
								// 封面的url
								const coverUrl = `${UPLOAD_URL}/img/${this.fileName}.${suffix}`
								// 保存封面
								fs.writeFileSync(coverPath, file, 'binary')
								this.coverPath = `/img/${this.fileName}.${suffix}`
								this.cover = coverUrl
								resolve(this)
							}
						}
						// 解压图书
						try {
							this.unzip()
							this.parseContents(epub).then( ({ chapters, chapterTree }) => {
								// 图书的目录
								this.contents = chapters
								this.contentsTree = chapterTree
								// 获取图书封面
								epub.getImage(cover, handleGetImage)
							})
							// reject(this)
						} catch (e) {
							reject(e)
						}
					}
				}
			})
			// 解析
			epub.parse()
		})
	}

	unzip() {
		const AdmZip = require('adm-zip')
		// console.log(Book.genPath(this.path))
		// const zip = new AdmZip(Book.genPath(this.path))
		const zip = new AdmZip(Book.genPath(this.path))
		// 保存文件
		zip.extractAllTo(Book.genPath(this.unzipPath), true)
	}

	// 获取目录
	parseContents(epub) {
		function getNcxFilePath() {
			const spine = epub && epub.spine
			const manifest = epub && epub.manifest
			const nxc = spine.toc && spine.toc.href
			const id = spine.toc && spine.toc.id
			console.log('spine', spine.toc, nxc, id, manifest[id].href)
			if(nxc) {
				return nxc
			} else {
				return manifest[id].href
			}
		}

		// level为目录层级
		function findParent(array, level = 0, pid = '') {
			// 遍历目录
			return array.map(item => {
				item.level = level
				item.pid = pid
				// 当存在二级目录时，即存在子目录时
				if(item.navPoint && item.navPoint.length > 0) {
					// 递归遍历子目录
					item.navPoint = findParent(item.navPoint, level + 1, item['$'].id)
				} else if(item.navPoint) {
					// 目录层级加1
					item.navPoint.level = level + 1
					item.navPoint.pid = item['$'].id
				}
				return item
			})
		}

		function flatten(array) {
			// 将树结构转化为一维结构
			return [].concat(...array.map(item => {
				if(item.navPoint && item.navPoint.length > 0) {
					return [].concat(item, ...flatten(item.navPoint))
				} else if(item.navPoint) {
					return [].concat(item, item.navPoint)
				}
				return item
			}))
		}

		// 获取文件路径
		const ncxFilePath = Book.genPath(`${this.unzipPath}/${getNcxFilePath()}`)
		if(fs.existsSync(ncxFilePath)) {
			return new Promise((reslove, reject) => {
				// 读取目录文件
				const xml = fs.readFileSync(ncxFilePath, 'utf-8')
				const dir = path.dirname(ncxFilePath).replace(UPLOAD_PATH, '')
				const fileName = this.fileName
				const unzipPath = this.unzipPath
				xml2js(xml, {
					explicitArray: false,
					ignoreAttrs: false
				}, function(err, json) {
					if(err) {
						reject(err)
					} else {
						// console.log('xml', json)
						// 获取目录对象
						const navMap = json.ncx.navMap
						if(navMap.navPoint && navMap.navPoint.length > 0) {
							navMap.navPoint = findParent(navMap.navPoint)
							// 将树状结构转换为一维结构
							const newNavMap = flatten(navMap.navPoint)
							const chapters = []
							newNavMap.forEach((chapter, index) => {
								const src = chapter.content['$'].src
								chapter.id = `${src}`
								chapter.href = `${dir}${src}`.replace(unzipPath, '')
								chapter.text = `${UPLOAD_URL}${dir}/${src}`
								// console.log(chapter.text)
								// 解析目录结构
								chapter.label = chapter.navLabel.text || ''
								// if(nav && nav.navLabel) {
								// 	chapter.label = nav.navLabel.text || ''
								// } else {
								// 	chapter.label = ''
								// }
								// chapter.level = nav.level
								// chapter.pid = nav.pid
								chapter.navId = chapter['$'].id
								chapter.fileName = fileName
								chapter.order = index + 1
								// console.log(chapter)
								chapters.push(chapter)
							})
							// 返回到前端的树形结构数据
							// const chapterTree = []
							// // 遍历目录
							// chapters.forEach(c => {
							// 	c.children = []
							// 	if(c.pid === '') {	// 一级目录
							// 		chapterTree.push(c)
							// 	} else {
							// 		const parent = chapters.find( _ => _.navId === c.pid )
							// 		parent.children.push(c)
							// 	}
							// })

							// 获取目录
							const chapterTree = Book.genContentsTree(chapters)
							// console.log(chapters)
							// console.log(chapterTree)
							reslove({ chapters, chapterTree })
						} else {
							reject(new Error('目录解析失败，目录数为0'))
						}
					}
				})
			})
		} else {
			throw new Error('目录文件不存在')
		}
	}

	toDb() {
		return {
			fileName: this.fileName,
			cover: this.cover,
			title: this.title,
			author: this.author,
			publisher: this.publisher,
			bookId: this.fileName,
			language: this.language,
			rootFile: this.rootFile,
			originalName: this.originalName,
			filePath: this.filePath,
			unzipPath: this.unzipPath,
			coverPath: this.cover,
			createUser: this.createUser,
			createDt: this.createDt,
			updateDt: this.updateDt,
			updateType: this.updateType,
			category: this.category,	// 分类
			categoryText: this.categoryText
		}
	}

	getContents() {
		return this.contents
	}

	// 重置方法
	reset() {
		if(Book.pathExists(this.filePath)) {
			// console.log('删除文件...')
			fs.unlinkSync(Book.genPath(this.filePath))
		}
		if(!Book.pathExists(this.coverPath)) {
			console.log('删除封面...')
			// fs.unlinkSync(Book.genPath(this.coverPath))
		}
		if(Book.pathExists(this.unzipPath)) {
			// console.log('删除解压目录...')
			fs.rmdirSync(Book.genPath(this.unzipPath), { recursive: true })
		}
		// console.log('this222', this)
	}

	// 拼接绝对路径
	static genPath(path) {
		if (!path.startsWith('/')) {
			path = `/${path}`
		}
		return `${UPLOAD_PATH}${path}`
	}

	static pathExists(path) {
		if(path.startsWith(UPLOAD_PATH)) {
			return fs.existsSync(path)
		} else {
			// console.log('3333333' ,fs.existsSync(Book.genPath(path)))
			return fs.existsSync(Book.genPath(path))
		}
	}

	static genCoverUrl(book) {
		const { cover } = book
		if (+book.updateType === 0) {
			if(cover) {
				// 新的电子书
				if (cover.startsWith('/')) {
					return `${OLD_UPLOAD_URL}${cover}`
				} else {
					return `${OLD_UPLOAD_URL}/${cover}`
				}
			} else {
				return null
			}
		} else {
			if(cover) {
				// 新的电子书
				if (cover.startsWith('/')) {
					return `${UPLOAD_URL}${cover}`
				} else {
					return `${UPLOAD_URL}/${cover}`
				}
			} else {
				return null
			}
		}
	}

	static genContentsTree(contents) {
		// const { contents } = book
		if(contents) {
			// 遍历目录
			const contentsTree = []
			contents.forEach(c => {
				c.children = []
				if(c.pid === '') {	// 一级目录
					contentsTree.push(c)
				} else {
					const parent = contents.find( _ => _.navId === c.pid )
					parent.children.push(c)
				}
			})
			return contentsTree
		}
	}
}



module.exports = Book